package level.editor.view.group;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;

import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.border.Border;

import level.editor.view.group.TabbedPane.TabTransferData;

public class SinglePanel extends JPanel
{

	public SinglePanel(BorderLayout borderLayout)
	{
		super(borderLayout);
		this.setBorder(null);
		init();
	}

	private void init()
	{
		new DropTarget(this, DnDConstants.ACTION_COPY_OR_MOVE,
				new SDropTargetListener(), true);
	}

	private class SDropTargetListener implements DropTargetListener
    {
            @Override
            public void dragEnter(DropTargetDragEvent e)
            {
                    // System.out.println("DropTarget.dragEnter: " +
                    // DnDTabbedPane.this);

                    if (isDragAcceptable(e))
                    {
                            e.acceptDrag(e.getDropAction());
                    }
                    else
                    {
                            e.rejectDrag();
                    } // if
            }

            @Override
            public void dragExit(DropTargetEvent e)
            {
                    setBorder(null);
            }

            @Override
            public void dropActionChanged(DropTargetDragEvent e)
            {
            }

            @Override
            public void dragOver(final DropTargetDragEvent e)
            {
                    setBorder(BORDER);
            }

            @Override
            public void drop(DropTargetDropEvent a_event)
            {
                    // System.out.println("DropTarget.drop: " + DnDTabbedPane.this);

                    if (isDropAcceptable(a_event))
                    {
                            convertTab(getTabTransferData(a_event));
                            a_event.dropComplete(true);
                    }
                    else
                    {
                            a_event.dropComplete(false);
                    }

                    setBorder(null);
                    repaint();
            }

            public boolean isDragAcceptable(DropTargetDragEvent e)
            {
                    Transferable t = e.getTransferable();
                    if (t == null)
                    {
                            System.out.println("No transferable");
                            return false;
                    } // if

                    DataFlavor[] flavor = e.getCurrentDataFlavors();
                    if (!t.isDataFlavorSupported(flavor[0]))
                    {
                            System.out.println("No supported data flavor");
                            return false;
                    } // if

                    TabTransferData data = getTabTransferData(e);
                    TabbedPane pane = data.getTabbedPane();

                    if (pane != null && data.getTabIndex() >= 0)
                    {
                            return true;
                    }

                    return false;
            }

            public boolean isDropAcceptable(DropTargetDropEvent e)
            {
                    Transferable t = e.getTransferable();
                    if (t == null)
                    {
                            return false;
                    } // if

                    DataFlavor[] flavor = e.getCurrentDataFlavors();
                    if (!t.isDataFlavorSupported(flavor[0]))
                    {
                            return false;
                    } // if

                    TabTransferData data = getTabTransferData(e);
                    TabbedPane pane = data.getTabbedPane();

                    if (pane != null && data.getTabIndex() >= 0)
                    {
                            return true;
                    }

                    return false;
            }
    }

    private void convertTab(TabTransferData tabTransferData)
    {
            Group group = (Group) getParent();
            TabbedPane source = tabTransferData.getTabbedPane();
            int sourceIndex = tabTransferData.getTabIndex();
            if (sourceIndex < 0)
            {
                    return;
            }
            Item item = (Item) source.getComponentAt(sourceIndex);
            source.remove(sourceIndex);
            group.add(item);
    }

    private TabTransferData getTabTransferData(DropTargetDropEvent a_event)
    {
            try
            {
                    TabTransferData data = (TabTransferData) a_event.getTransferable()
                                    .getTransferData(FLAVOR);
                    return data;
            }
            catch (Exception e)
            {
                    e.printStackTrace();
            }

            return null;
    }

    private TabTransferData getTabTransferData(DropTargetDragEvent a_event)
    {
            try
            {
                    TabTransferData data = (TabTransferData) a_event.getTransferable()
                                    .getTransferData(FLAVOR);
                    return data;
            }
            catch (Exception e)
            {
                    e.printStackTrace();
            }

            return null;
    }

    private static final String NAME = "TabTransferData";
    private final DataFlavor FLAVOR = new DataFlavor(
                    DataFlavor.javaJVMLocalObjectMimeType, NAME);
    private static final Border BORDER = BorderFactory.createMatteBorder(5, 5,
                    5, 5, Color.GRAY);

}